<template>
  <el-container :showFooter="true" :autoFixHeight="true">
    <el-header>
      <div style="margin-top: 20px;">
        <el-page-header @back="back">
          <template slot="title">返回列表</template>
          <template slot="content">
            <el-button type="success" icon="el-icon-check" v-on:click="save(false)">保存</el-button>
            <el-button type="success" icon="el-icon-finished" v-on:click="save(true)">提交</el-button>
            <el-button type="primary" icon="el-icon-s-flag" v-on:click="showVersion = true">版本</el-button>
          </template>
        </el-page-header>
      </div>
    </el-header>
    <el-main style="padding:0;">
      <el-tabs @tab-click="tabClick">
        <el-tab-pane label="基本信息">
          <el-container>
            <el-main>
              <el-form label-width="150px">
                <el-row>
                  <el-col :span="12">
                    <el-form-item label="名称">
                      <el-input v-model="model.name" autocomplete="off"></el-input>
                    </el-form-item>
                  </el-col>
                  <el-col :span="12">
                    <el-form-item label="数据库连接">
                      <el-select v-model="model.connectionName" filterable placeholder="请选择一个连接">
                        <el-option v-for="item in connections" :key="item.name" :label="item.name + '（'+item.provider+'）'" :value="item.name" ></el-option>
                      </el-select>
                    </el-form-item>
                  </el-col>
                </el-row>
                <el-row>
                  <el-col :span="12">
                    <el-form-item label="超时时间">
                      <el-slider v-model="model.timeout" :min="0" :max="600" :step="5"></el-slider>
                      <label class="control-label pull-left">
                        <b style="color:green">{{model.timeout}}</b>秒，默认值：60秒
                      </label>
                    </el-form-item>
                  </el-col>
                  <el-col :span="12">
                    <el-form-item label="命令类型">
                      <el-select v-model="model.commandType" placeholder="请选择命令类型">
                        <el-option
                          v-for="(commandType, index) in commandTypes"
                          :key="index"
                          :label="commandType.label"
                          :value="commandType.value"
                        ></el-option>
                      </el-select>
                    </el-form-item>
                  </el-col>
                </el-row>
                <el-row>
                  <el-col :span="24">
                    <el-form-item label="描述(可选)">
                      <el-input v-model="model.description" type="textarea" :rows="6"></el-input>
                    </el-form-item>
                  </el-col>
                </el-row>
              </el-form>
              <el-table border min-height="400" :data="model.parameters" style="width: 100%;">
                <el-table-column label="名称" width="150">
                  <template slot-scope="scope">
                    <el-input v-model="scope.row.name"></el-input>
                  </template>
                </el-table-column>
                <el-table-column label="参数名" width="150">
                  <template slot-scope="scope">
                    <el-input v-model="scope.row.parameterName"></el-input>
                  </template>
                </el-table-column>
                <el-table-column label="参数类型" width="150">
                  <template slot-scope="scope">
                    <mf-typeSelect v-model="scope.row.type" placeholder="请选择参数类型"></mf-typeSelect>
                  </template>
                </el-table-column>
                <el-table-column label="传参方式" width="150">
                  <template slot-scope="scope">
                    <el-select v-model="scope.row.direction" placeholder="请选择传参方式">
                      <el-option v-for="(direction, index) in parameterDirections" :key="index" :label="direction.label" :value="direction.value" ></el-option>
                    </el-select>
                  </template>
                </el-table-column>
                <el-table-column label="精度" width="80">
                  <template slot-scope="scope">
                    <el-input-number v-model="scope.row.precision" :controls="false" :min="0" :max="10" ></el-input-number>
                  </template>
                </el-table-column>
                <el-table-column label="小数位" width="80">
                  <template slot-scope="scope">
                    <el-input-number v-model="scope.row.scale" :controls="false" :min="0" :max="10"></el-input-number>
                  </template>
                </el-table-column>
                <el-table-column label="范围" width="80">
                  <template slot-scope="scope">
                    <el-input-number v-model="scope.row.size" :controls="false" :min="0" :max="10"></el-input-number>
                  </template>
                </el-table-column>
                <el-table-column label="可空" width="60">
                  <template slot-scope="scope">
                    <el-checkbox v-model="scope.row.nullable"></el-checkbox>
                  </template>
                </el-table-column>
                <el-table-column label="默认值" width="100">
                  <template slot-scope="scope">
                    <el-input v-model="scope.row.defaultValue"></el-input>
                  </template>
                </el-table-column>
                <el-table-column label="参数描述" min-width="200">
                  <template slot-scope="scope">
                    <el-input v-model="scope.row.description"></el-input>
                  </template>
                </el-table-column>
                <el-table-column fixed="right" header-align="center" align="center" width="40">
                  <template slot="header">
                    <el-button type="text" icon="el-icon-circle-plus" @click="model.parameters.push({name:'', parameterName:'', type:'System.String', direction:'Input', precision:0, scale:0, size:0, nullable: false, defaultValue:null })"></el-button>
                  </template>
                  <template slot-scope="scope">
                    <el-button type="text" icon="el-icon-remove" @click="model.parameters.remove(scope.row)"></el-button>
                  </template>
                </el-table-column>
              </el-table>
            </el-main>
          </el-container>
        </el-tab-pane>
        <el-tab-pane label="SQL脚本">
          <el-container>
            <el-header>
              <div style="padding:10px;">
                <el-button type="text" icon="el-icon-s-tools" v-on:click="showFunctions = true">宏</el-button>
                <el-button type="text" icon="el-icon-search" v-on:click="showPreview = true">预览</el-button>
              </div>
            </el-header>
            <el-main style="padding:0; overflow:hidden">
              <mf-monacoEditor ref="editor" v-model="model.text" language="sql" theme="vs-dark"></mf-monacoEditor>
            </el-main>
          </el-container>
        </el-tab-pane>
        <el-tab-pane label="接口范例">
          <el-container>
            <el-header>
              <el-button type="text" icon="el-icon-s-tools" v-on:click="showApiTest = true">接口测试</el-button>
            </el-header>
            <el-main>
              <el-tabs v-model="activedApi" tab-position="left" style="height:100%;" @tab-click="apiSampleClick">
                <el-tab-pane v-for="(api, i) in apiSamples" :key="i" :name="api.name" :label="api.label">
                  <el-container>
                    <el-main>
                      <el-form label-width="100px">
                        <el-form-item label="URL">
                          <el-input :value="`${api.url}/${api.name}`" disabled autocomplete="off"></el-input>
                        </el-form-item>
                        <el-form-item label="请求报文">
                          <el-input :value="api.requestTxt" disabled type="textarea" :rows="10"></el-input>
                        </el-form-item>
                        <el-form-item label="响应结果">
                          <el-input :value="api.responseTxt" disabled type="textarea" :rows="10"></el-input>
                        </el-form-item>
                      </el-form>
                    </el-main>
                  </el-container>
                </el-tab-pane>
              </el-tabs>
            </el-main>
          </el-container>
        </el-tab-pane>
      </el-tabs>
      <el-drawer :title="'[' + model.name + ']所有版本'" :visible.sync="showVersion" @closed="versionClosed" direction="rtl" size="40%" >
        <mf-versioning :commandDev="model" comparable :show="showVersion" @compare="compareVersion" ></mf-versioning>
      </el-drawer>
      <el-dialog title="自定义函数" width="600" :visible.sync="showFunctions" :close-on-click-modal="false">
        <el-container>
          <el-main>
            <el-table ref="functionGrid" height="300" :data="functions" highlight-current-row border @row-click="functionGridClick" @row-dblclick="functionGridDbClick" style="width: 100%;" >
              <el-table-column prop="name" header-align="left" align="left" label="函数名" width="200"></el-table-column>
              <el-table-column prop="description" header-align="left" align="left" label="说明"></el-table-column>
            </el-table>
          </el-main>
        </el-container>
        <div slot="footer" class="container-fluid">
          <el-button type="primary" icon="el-icon-edit" @click="functionClick">插入到当前光标位置</el-button>
        </div>
      </el-dialog>
      <el-dialog title="预览" width="600" :visible.sync="showPreview" @open="openPreviewDialog" @close="closePreviewDialog" :close-on-click-modal="false" >
        <div class="container-fluid">
          <template v-if="previewRequest.parameters && previewRequest.parameters.length > 0">
            <h5>参数列表</h5>
            <el-table border max-height="200" :data="previewRequest.parameters" style="width: 100%;" >
              <el-table-column prop="ParameterName" label="参数名" width="150">
                <template slot-scope="scope">
                  <b>{{scope.row.parameterName}}</b>
                </template>
              </el-table-column>
              <el-table-column prop="Type" label="类型" width="150">
                <template slot-scope="scope">{{getType(scope.row.type)}}</template>
              </el-table-column>
              <el-table-column prop="Direction" label="传参方式" width="150">
                <template slot-scope="scope">{{getDirection(scope.row.direction)}}</template>
              </el-table-column>
              <el-table-column prop="DefaultValue" label="参数值">
                <template slot-scope="scope">
                  <el-input v-model="scope.row.defaultValue"></el-input>
                </template>
              </el-table-column>
            </el-table>
          </template>
          <h5>执行结果</h5>
          <el-table height="300" :data="previewResult.result.rows" border style="width: 100%;">
            <el-table-column type="index"></el-table-column>
            <el-table-column
              v-for="(column, index) in previewResult.result.columns"
              :key="index"
              header-align="left"
              align="left"
              show-overflow-tooltip
              :label="column.name"
              width="100"
            >
              <template slot-scope="scope">
                {{ scope.row.dataItem[column.name] }}
              </template>
            </el-table-column>
          </el-table>
        </div>
        <div slot="footer" class="container-fluid">
          <el-select v-model="previewRequest.MaxRowCount" style="width:80px">
            <el-option :value="50" label="50行"></el-option>
            <el-option :value="100" label="100行"></el-option>
            <el-option :value="200" label="200行"></el-option>
          </el-select>
          <el-button type="primary" icon="el-icon-refresh" @click="preview"></el-button>
        </div>
      </el-dialog>
      <el-dialog title="接口测试" width="600" :visible.sync="showApiTest" @open="openApiTestDialog" @close="closeApiTestDialog" :close-on-click-modal="false">
        <el-container>
          <el-main>
            <el-form label-width="100px">
              <el-form-item label="参考地址">
                <el-input :value="apiTestModel.url" readonly>
                  <el-button slot="append" icon="el-icon-video-play" @click="testApi"></el-button>
                </el-input>
              </el-form-item>
              <el-form-item label="http方法">
                <el-select v-model="apiTestModel.method" placeholder="请选择">
                  <el-option label="GET" value="GET"></el-option>
                  <el-option label="POST" value="POST"></el-option>
                </el-select>
              </el-form-item>
              <el-form-item label="请求报文">
                <el-input type="textarea" :disabled="apiTestModel.method === 'GET'" :rows="8" v-model="apiTestModel.requestTxt"></el-input>
              </el-form-item>
              <el-form-item label="响应结果">
                <el-input type="textarea" :rows="8" v-model="apiTestModel.responseTxt"></el-input>
              </el-form-item>
            </el-form>
          </el-main>
        </el-container>
      </el-dialog>
    </el-main>
  </el-container>
</template>
<script>
import { mapGetters, mapState, mapActions } from 'vuex';
const STORE_MODULE = {
  "getters": [
    "functions",
    "connections",
    "commandTypes",
    "types",
    "parameterDirections"
  ],
  "name": "command",
  "actions": [
    "item",
    "create",
    "update"
  ]
};
export default {
  data() {
    return {
      newItem: false,
      showConnections: false,
      showFunctions: false,
      showPreview: false,
      showVersion: false,
      showApiTest: false,
      previewRequest: {
        name: "",
        provider: "",
        connectionString: "",
        commandText: "",
        commandType: 1,
        timeout: 600,
        parameters: [],
        maxRowCount: 50
      },
      previewResult: {
        result: {
          columns: [],
          rows: []
        },
        rowCount: 0
      },
      model: {
        name: "",
        text: "",
        connectionName: "",
        commandType: "Text",
        timeout: 60,
        description: "",
        submitted:false,
        parameters: []
      },
      versionRequest: {
        pageIndex: 1,
        pageSize: 10,
        sortFields: {
          CreateTime: true
        },
        parameters:{

          name: this.$route.params.name
        }
      },
      versionResult: {
        columns: [],
        result: [],
        pageCount: 0,
        rowCount: 0
      },
      currentFunction: null,
      activedApi: "dataquery",
      apiTestModel: {
        method: 'GET',
        url: null,
        requestTxt: null,
        responseTxt: null
      }
    };
  },
  computed: {
    ...mapGetters(STORE_MODULE.getters),
    currentApi(){
      return this.apiSamples.singleOrDefault(a=> a.name == this.activedApi);
    },
    apiSamples() {
      let parameters = [];
      this.model.parameters.forEach((par) => {
        parameters.push(`"${par.name}": //${this.getType(par.type)}`);
      });
      let url = "/data";
      let paraList = parameters.join(",\n\t");
      return [
        {
          name: 'dataquery',
          label: '列表查询',
          url: url,
          requestTxt: `{\n\t${paraList}\n}`,
          responseTxt: '{\n\t"success": true, \n\t"data": {\n\t\t"rowCount”: 0,\n\t\t"result": []\n\t}\n}'
        },
        {
          name: 'pagedquery',
          label: '分页查询',
          url: url,
          requestTxt: `{\n\t"pageIndex": 0,\n\t"pageSize": 20,\n\t"parameters": {\n\t\t${paraList}\n\t\t}\n}`,
          responseTxt: '{\n\t"success": true, \n\t"data": {\n\t\t"rowCount": 0,\n\t\t"pageCount": 0,\n\t\t"result": []\n\t}\n}'
        },
        {
          name: 'objectquery',
          label: '对象查询',
          url: url,
          requestTxt: `{\n\t${paraList}\n}`,
          responseTxt: '{\n\t"success": true, \n\t"data": {\n\t}\n}'
        },
        {
          name: 'dataoperate',
          label: '写操作',
          url: url,
          requestTxt: `{\n\t${paraList}\n}`,
          responseTxt: '{\n\t"success": true, \n\t"data": 0\n}'
        }
      ]
    }
  },
  created() {
    this.init();
    this.loadObject();
  },
  methods: {
    ...mapActions(STORE_MODULE.name, STORE_MODULE.actions),
    init() {
      if(this.connections.length <= 0)
        confirm(
          "当前没有可用的数据库连接，要现在创建连接吗？",
          "提示",
          "info",
          () => {
            this.$router.push({ name: "connection" });
          }
        );
    },
    loadObject() {
      let name = this.$route.params.name;
      this.model.name = name;
      this.item(name).then(response => {
        if (response.success){
          if (response.data){
            this.model = response.data;
            this.model.parameters = this.model.parameters || [];
          }
          else{
            this.newItem = true;
          }
        }
      });
    },
    loadVersions() {
      this.$service.command
        .queryVersions({ data: this.versionRequest })
        .then(response => {
          this.versionResult = response.data;
        });
    },
    getType(val) {
      let item = this.types.singleOrDefault(
        p => p.value == val
      );
      return item ? item.label : "";
    },
    getDirection(val) {
      let item = this.parameterDirections.singleOrDefault(
        p => p.value == val
      );
      return item ? item.label : "";
    },
    tabClick(tab, event) {
      this.$nextTick(() => {
        if (this.$refs.editor)
          this.$refs.editor.layout();
      });
    },
    back() {
      this.$router.push({ name: "command" });
    },
    save(commit) {
      let task = this.newItem ? this.create : this.update;
      console.log(this.model)
      task(this.model).then(response => {
        if (response.success) {
          this.newItem = false;
          this.model = response.data;
          if (commit) {
            prompt("请填写备注", "提交代码", "", val => {
              this.$service.commandVersion
                .commit({ data: { name: this.model.name, comment: val } })
                .then(response => {
                  if (response.success) {
                    alert("提交成功", "消息", "success", this.back);
                  }
                });
            });
          } else {
            alert("保存成功", "消息", "success");
          }
        } else {
          if (response.message) alert(response.message, "错误", "error");
        }
      });
    },
    preview() {
      this.$service.command
        .test({ data: this.previewRequest })
        .then(response => {
          if (response.success) {
            this.previewResult = response.data;
          } else {
            if (response.message) alert(response.message, "错误", "error");
          }
        });
    },
    openPreviewDialog() {
      let conn = this.connections.singleOrDefault(
        item => item.name == this.model.connectionName
      );

      this.previewRequest.name = this.model.name;
      this.previewRequest.provider = conn.provider;
      this.previewRequest.connectionString = conn.connectionString;
      this.previewRequest.commandText = this.model.text;
      this.previewRequest.timeout = this.model.timeout;
      this.previewRequest.commandType = this.model.commandType;
      let pars = JSON.stringify(this.model.parameters);
      pars = JSON.parse(pars);
      this.previewRequest.parameters = pars;
      if (
        this.previewRequest.parameters &&
        this.previewRequest.parameters.length > 0
      ) {
      } else {
        this.preview();
      }
    },
    closePreviewDialog() {
      this.previewRequest = {
        name: "",
        provider: "",
        connectionString: "",
        commandText: "",
        timeout: 600,
        commandType: 1,
        parameters: [],
        maxRowCount: 50
      };
      this.previewResult = {
        result: {
          columns: [],
          rows: []
        },
        rowCount: 0
      };
    },
    versionClosed() {
      this.showVersion = false;
    },
    connectionClosed() {
      this.showConnections = false;
    },
    functionClick() {
      let expression = this.currentFunction.expression;
      this.insertFunction(expression);
    },
    insertFunction(functionExpression) {
      this.$refs.editor.insertContent(functionExpression);
      this.currentFunction = null;
      this.showFunctions = false;
    },
    functionGridClick(row) {
      this.currentFunction = row;
    },
    functionGridDbClick(row) {
      this.insertFunction(row.expression);
    },
    compareVersion(arg) {
      arg.callback(this.model);
    },
    openApiTestDialog(){

      this.apiTestModel.url = this.currentApi.url + "/"+ this.currentApi.name + "/" + this.model.name;
      this.apiTestModel.requestTxt = this.currentApi.requestTxt;
      this.apiTestModel.responseTxt = this.currentApi.responseTxt;
    },
    closeApiTestDialog(){

      this.apiTestModel.url = null;
      this.apiTestModel.method = 'GET';
      this.apiTestModel.requestTxt = null;
      this.apiTestModel.responseTxt = null;
    },
    apiSampleClick(tab, event){

    },
    testApi(){
      let request = JSON.parse(this.apiTestModel.requestTxt);
      this.$service.data[this.currentApi.name]({method: this.apiTestModel.method, routeData:{name: this.model.name}, data:request}).then(r=>{
        let response = r.data;
        this.apiTestModel.responseTxt = JSON.stringify(response);
      });
    }
  }
};
</script>
